#include <Arduino.h>
#include "queue.h"
#include "bucket_plant_water.h"
#include "mainfunc.h"
#include "utils.h"
#include "Http.h"
#include "config.h"
#include "espcrypto.h"
#include "JsonParse.h"
#include "global.h"
#include "NTPTime.h"
#include <OneButton.h>
#include "httpfunc.h"
#include <TimeLib.h>
#include <ESP32Time.h>
#include "BizUtils.h"
#include "ntc.h"

#include "ActionCtrl.h"
#include "SensorData.h"
#include "Log.h"

extern int BPW_PUMP_PIN;
extern int BPW_PUMP2_PIN;
// 8:绿色  9：蓝色  10：红色（pin）
extern int RED_LIGHT_PIN;
extern int GREEN_LIGHT_PIN;
extern int BLUE_LIGHT_PIN;
extern int BEEP_PIN;

const int TEMP_PIN = 1;
const int WATER_PIN = 3;
const int VCC_PIN = 4;
// const int VCC_SWITCH__PIN = 6;

static bool isAppStartValue = false;
bool isConnectWiFi = false;

int notifyWaterTimes = 0;
esp_sleep_wakeup_cause_t wakeupReason=ESP_SLEEP_WAKEUP_UNDEFINED;

extern ESP32Time rtc;
// extern RTC_DATA_ATTR B gloablInterValAction[10];
// extern RTC_DATA_ATTR B gloablWeekAction[7][10];

RTC_DATA_ATTR int bootCount = 0;

Queue vccQueue;

void mqttCallBack(char *s1, unsigned char *s2, unsigned int i)
{
  Serial.println(s1);
}



esp_sleep_wakeup_cause_t getWakeupReason(){
   return  esp_sleep_get_wakeup_cause();
}

int print_wakeup_reason()
{

  ++bootCount;
  Serial.println("Boot number: " + String(bootCount));
  esp_sleep_wakeup_cause_t wakeup_reason;
  wakeup_reason = esp_sleep_get_wakeup_cause();
 
  switch (wakeup_reason)
  {
  case ESP_SLEEP_WAKEUP_EXT0:
    Serial.println("Wakeup caused by external signal using RTC_IO");
    break;
  case ESP_SLEEP_WAKEUP_EXT1:
    Serial.println("Wakeup caused by external signal using RTC_CNTL");
    break;
  case ESP_SLEEP_WAKEUP_TIMER:
    Serial.println("Wakeup caused by timer");
    break;
  case ESP_SLEEP_WAKEUP_TOUCHPAD:
    Serial.println("Wakeup caused by touchpad");
    break;
  case ESP_SLEEP_WAKEUP_GPIO:
    Serial.println("Wakeup caused by gpio");

    break;
    
  case ESP_SLEEP_WAKEUP_ULP:
    Serial.println("Wakeup caused by ULP program");
    break;
  default:
  {

    Serial.printf("Wakeup was not caused by deep sleep: %d\n", wakeup_reason);
    break;
  }
  }

  return 1;
}

 

bool globalInitBPW()
{

  parseFromPreference();
  int result = print_wakeup_reason();
  if (result == 0)
  {
    return false;
  }

  setUpWiFi();
  setupCrypto();
  // setupMQTT();
  //  subscribe(cmd);
  //  setMqttCallback(mqttCallBack);
  // analogSetPinAttenuation(1, ADC_ATTENDB_MAX); // 设置信号输入衰减

  return true;
}

void startApp(bool on)
{
  isAppStartValue = on;
}

// 给睡眠唤醒用的
bool isAppStart()
{
  return isAppStartValue;
}

 
void setupBPW()
{
  config();
  initPortBPW();
  attachButtonClick();
  attachGlobalTimer();
}

void initPortBPW()
{
  setBeepPin(18);
  pinMode(RED_LIGHT_PIN, OUTPUT);
  pinMode(GREEN_LIGHT_PIN, OUTPUT);
  pinMode(BLUE_LIGHT_PIN, OUTPUT);
  pinMode(BPW_PUMP_PIN, OUTPUT);
  pinMode(BPW_PUMP2_PIN, OUTPUT);
  pinMode(BEEP_PIN, OUTPUT);
  // pinMode(VCC_SWITCH__PIN, OUTPUT);
  pinMode(VCC_PIN, INPUT);
  pinMode(WATER_PIN, INPUT);
  pinMode(TEMP_PIN, INPUT);
}


float getTemp()
{
  int temp = analogRead(TEMP_PIN);

  return temp * 1.0 / 1.0;
}

int getTempPinValue()
{
  int temp = analogRead(TEMP_PIN);
  return temp;
}

int getVccPinValue()
{
  // digitalWrite(VCC_SWITCH__PIN, 0);
  int vcc = analogRead(VCC_PIN);
  // digitalWrite(VCC_SWITCH__PIN, 1);
  return vcc;
}

float getVcc()
{
  if (!isPump())
  {
    int vcc = getVccPinValue();
    //printStr("vcc", vcc);
    // digitalWrite(VCC_SWITCH__PIN, 1);
    vccQueue.forceEnqueue(vcc);
  }
  float avrVcc = vccQueue.average();
  return convertVcc(avrVcc);


  
}

float convertVcc(int vcc){
 float total = (2810 - 2200) * 1.0;

  float percent = (vcc - 2200) * 1.0 / total;
  if (percent > 1)
  {
    percent = 1;
  }
  if (percent < 0)
  {
    percent = 0;
  }
  // float roundedNumber = round(percent * 100.0) / 100.0;

  float result = 1.0 * ((int)(percent * 100)) / 100;
  return result;
}

int getWater()
{
  int water = analogRead(WATER_PIN);
  return water;
}

void sendDataBPW()
{
  String temp = readNTCStr();
  float vcc = getVcc();
  int water = getWater();



  printStr("temp", temp);
  printStr("vcc", vcc);
  printStr("water", water);




  sendData(temp, vcc, getVccPinValue(), isWater(), getWater());

  

  sendLog();
  if (isReboot())
  {
    printStr("模式改变重启系统");
    delay(2000);
    ESP.restart();
  }
}

static int pumpIdleTime=0;
bool checkPumpIdle()
{
  float vccPinAvr = getSensorPinValue("vcc");

  
  if (isPump())
  {
    float currentVcc = getVccPinValue();
    float diffVcc = currentVcc - vccPinAvr;
   
    if (diffVcc > -100)
    { 
      pumpIdleTime++;
      // 压降小于100，空转
      if(pumpIdleTime>=3){
        pumpIdleTime=0;
        return true;
      }
    }else{
      pumpIdleTime=0;
      return false;
    }
  }
  return false;
}

int flat = 0;
bool checkPumpOverload()
{
  float vccPinAvr = getSensorPinValue("vcc");

  if (isPump())
  {
    flat++;
    float currentVcc = getVccPinValue();
    float diffVcc = currentVcc - vccPinAvr;
    if (diffVcc < -480)//改成500试试
    {  
       //switchPump();
       //switchRandomPump();
      return true;
    }
    // else
    // {
    //    //pump(true);
    //    pump1(true);
    //    if(getCurrentVcc()>=0.5){
    //       pump2(true);
    //    }
    // }
  }
  return false;
}

bool checkPumpPause()
{

  bool overload = isPumpOverload();
  bool ispump = isPump();
  bool isPause = isPumpPause();
  //printStr("overload", overload);
  //printStr("ispump", ispump);
  // printStr("isPause", isPause);

  if (overload && ispump && (!isPause))
  {
    printStr("过载保护暂停5秒");
    pumpPauseTime(5);
    return true;
  }

  return false;
}